package gamesdk.module {
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import gamesdk.framework.api.IGcManager;
	import gamesdk.framework.impl.GcManager;
	
	import gamesdk.extensions.tracelog.TraceLog;
	import gamesdk.framework.api.ILogManager;
	import gamesdk.framework.impl.LogManager;
	import gamesdk.module.core.IModuleConfigManager;
	import gamesdk.module.core.IModuleManager;
	import gamesdk.module.core.IModuleModelCenter;
	import gamesdk.module.core.IReflector;
	import gamesdk.module.core.IScreen;
	import gamesdk.module.core.IScreenManager;
	import gamesdk.module.display.ScreenManager;
	import gamesdk.module.module.ModuleConfigManager;
	import gamesdk.module.module.ModuleManager;
	import gamesdk.module.module.ModuleModelCenter;
	import gamesdk.module.module.RSLModuleManager;
	import gamesdk.module.reflection.Reflector;
	
	import robotlegs.bender.framework.api.IContext;
	CONFIG::flash_display {
		import flash.display.Sprite;
	}
	CONFIG::starling_display {
		import starling.display.Sprite;
	}
	
	/**
	 * ...
	 * @author hanxianming
	 */
	public class Launcher {
		private var _context:IContext;
		private var _moduleManager:IModuleManager;
		private var _modelCenter:IModuleModelCenter;
		private var _logManager:ILogManager;
		private var _configMnager:IModuleConfigManager;
		private var _screenManager:IScreenManager;
		private var _gcManager:GcManager;
		
		public function Launcher() {
		
		}
		
		public function launcher(nativeroot:DisplayObject, root:Sprite, xml:XML, dynamicLoad:Boolean = true):Launcher {
			
			GlobalsVars.nativeStage = nativeroot.stage;
			GlobalsVars.rootSprite = root;
			GlobalsVars.dynamicLoad = dynamicLoad;
			
			var url:String = nativeroot.loaderInfo.url;
			Reflector.instance.isLocal = !(url.indexOf("file://") == -1);
			
			initializeInject();
			initializeModule();
			
			_configMnager.setModulesConfig(xml);
			
			return this;
		}
		
		public function addScreen(screen:IScreen):void {
			_screenManager.addScreen(screen);
		}
		
		public function switchScreen(screenType:Object):void
		{
			_screenManager.switchScreen(screenType);
		}
		
		private function initializeInject():void {
			
			_modelCenter = new ModuleModelCenter();
			_modelCenter.registInstance(IModuleModelCenter, _modelCenter);
			_modelCenter.registInstance(IReflector, Reflector.instance);
			
			_logManager = new LogManager()
			_logManager.addLog(new TraceLog());
			_modelCenter.registInstance(ILogManager, _logManager);
			
			_configMnager = new ModuleConfigManager();
			_modelCenter.registInstance(IModuleConfigManager, _configMnager)
			
			_gcManager = new GcManager();
			_modelCenter.registInstance(IGcManager, _gcManager);
			
			_screenManager = new ScreenManager();
			_modelCenter.registInstance(IScreenManager, _screenManager);
			_modelCenter.intoInjectObject(_screenManager);
			
			
			_modelCenter.intoInjectObject(_modelCenter);
		
		}
		
		private function initializeModule():void {
			_moduleManager = GlobalsVars.dynamicLoad ? new RSLModuleManager() : new ModuleManager();
			_modelCenter.registInstance(IModuleManager, _moduleManager);
			_modelCenter.intoInjectObject(_moduleManager);
			_moduleManager.initialize();
		}
		
		public function context(value:IContext):Launcher {
			_context = value;
			
			return this;
		}
		
		public function dispatchEvent(event:Event):void {
			(_context.injector.getInstance(IEventDispatcher) as IEventDispatcher).dispatchEvent(event);
		}
	}
}